package example;

import client.DatabaseClient;
import model.KeyValue;

import lombok.extern.slf4j.Slf4j;

import java.util.*;

/**
 * 数据库使用示例
 * 展示API的使用方法和功能
 */
@Slf4j
public class DatabaseExample {
    
    private static final String SERVER_HOST = "localhost";
    private static final int SERVER_PORT = 8888;
    
    public static void main(String[] args) {
        log.info("=== 键值数据库使用示例 ===");
        
        // 创建客户端连接
        try (DatabaseClient client = new DatabaseClient(SERVER_HOST, SERVER_PORT)) {
            if (!client.connect()) {
                log.error("无法连接到服务器");
                return;
            }
            
            log.info("成功连接到数据库服务器");
            
            // 测试连接
            if (client.ping()) {
                log.info("服务器连接正常");
            }
            
            // 示例1: 基本CRUD操作
            basicCrudExample(client);
            
            // 示例2: 批量操作
            batchOperationExample(client);
            
            // 示例3: 集合操作
            collectionExample(client);
            
            // 示例4: 泛型支持
            genericExample(client);
            
            // 示例5: 性能测试
            performanceTest(client);
            
            // 获取统计信息
            showStatistics(client);
            
        } catch (Exception e) {
            log.error("示例执行失败: error={}", e.getMessage());
        }
    }
    
    /**
     * 基本CRUD操作示例
     */
    private static void basicCrudExample(DatabaseClient client) {
        log.info("\n=== 基本CRUD操作示例 ===");
        
        // 存储不同类型的值
        client.put("string_key", "Hello World");
        client.put("int_key", 123);
        client.put("double_key", 3.14159);
        client.put("boolean_key", true);
        client.put("list_key", Arrays.asList("a", "b", "c"));
        
        log.info("存储了5个不同类型的键值对");
        
        // 获取值
        String stringValue = client.get("string_key", String.class);
        Integer intValue = client.get("int_key", Integer.class);
        // 兼容double反序列化为BigDecimal的情况
        Object doubleObj = client.get("double_key", Object.class);
        Double doubleValue = null;
        if (doubleObj instanceof Double) {
            doubleValue = (Double) doubleObj;
        } else if (doubleObj instanceof java.math.BigDecimal) {
            doubleValue = ((java.math.BigDecimal) doubleObj).doubleValue();
        }
        Boolean booleanValue = client.get("boolean_key", Boolean.class);
        @SuppressWarnings("unchecked")
        List<String> listValue = client.get("list_key", List.class);
        
        log.info("获取的值: string={}, int={}, double={}, boolean={}, list={}", 
                stringValue, intValue, doubleValue, booleanValue, listValue);
        
        // 检查键是否存在
        boolean exists = client.containsKey("string_key");
        log.info("键 'string_key' 存在: {}", exists);
        
        // 更新值
        client.update("string_key", "Updated Hello World");
        String updatedValue = client.get("string_key", String.class);
        log.info("更新后的值: {}", updatedValue);
        
        // 获取所有键
        List<String> allKeys = client.getAllKeys();
        log.info("所有键: {}", allKeys);
        
        // 删除键
        client.delete("boolean_key");
        boolean deleted = client.containsKey("boolean_key");
        log.info("删除后键 'boolean_key' 存在: {}", deleted);
    }
    
    /**
     * 批量操作示例
     */
    private static void batchOperationExample(DatabaseClient client) {
        log.info("\n=== 批量操作示例 ===");
        
        // 批量插入
        Map<String, Object> batchData = new HashMap<>();
        for (int i = 1; i <= 10; i++) {
            batchData.put("batch_key_" + i, "value_" + i);
        }
        
        boolean batchPutSuccess = client.batchPut(batchData);
        log.info("批量插入10条数据: {}", batchPutSuccess ? "成功" : "失败");
        
        // 批量更新
        Map<String, Object> updateData = new HashMap<>();
        for (int i = 1; i <= 5; i++) {
            updateData.put("batch_key_" + i, "updated_value_" + i);
        }
        
        boolean batchUpdateSuccess = client.batchUpdate(updateData);
        log.info("批量更新5条数据: {}", batchUpdateSuccess ? "成功" : "失败");
        
        // 验证更新结果
        String updatedValue = client.get("batch_key_1", String.class);
        log.info("更新后的值: {}", updatedValue);
        
        // 批量删除
        List<String> keysToDelete = Arrays.asList("batch_key_1", "batch_key_2", "batch_key_3");
        boolean batchDeleteSuccess = client.batchDelete(keysToDelete);
        log.info("批量删除3条数据: {}", batchDeleteSuccess ? "成功" : "失败");
        
        // 验证删除结果
        boolean exists = client.containsKey("batch_key_1");
        log.info("删除后键 'batch_key_1' 存在: {}", exists);
    }
    
    /**
     * 集合操作示例
     */
    private static void collectionExample(DatabaseClient client) {
        log.info("\n=== 集合操作示例 ===");
        
        // 创建集合
        boolean createSuccess = client.createCollection("users", "用户信息集合");
        log.info("创建集合 'users': {}", createSuccess ? "成功" : "失败");
        
        // 在集合中存储数据
        client.putInCollection("users", "user1", "张三");
        client.putInCollection("users", "user2", "李四");
        client.putInCollection("users", "user3", "王五");
        client.putInCollection("users", "user1_age", 25);
        client.putInCollection("users", "user2_age", 30);
        client.putInCollection("users", "user3_age", 28);
        
        log.info("在集合中存储了6条数据");
        
        // 从集合中获取数据
        String user1 = client.getFromCollection("users", "user1", String.class);
        Integer user1Age = client.getFromCollection("users", "user1_age", Integer.class);
        log.info("用户1信息: name={}, age={}", user1, user1Age);
        
        // 创建另一个集合
        client.createCollection("products", "产品信息集合");
        client.putInCollection("products", "product1", "iPhone");
        client.putInCollection("products", "product2", "MacBook");
        client.putInCollection("products", "product1_price", 6999.0);
        client.putInCollection("products", "product2_price", 12999.0);
        
        log.info("创建了产品集合并存储了4条数据");
        
        // 获取所有集合
        List<Object> allCollections = client.getAllCollections();
        log.info("所有集合数量: {}", allCollections.size());
        
        // 从集合中删除数据
        client.deleteFromCollection("users", "user3");
        boolean user3Exists = client.containsKey("user3");
        log.info("删除后用户3存在: {}", user3Exists);
        
        // 删除集合
        client.deleteCollection("products");
        Object deletedCollection = client.getCollection("products");
        log.info("删除集合后获取结果: {}", deletedCollection);
    }
    
    /**
     * 泛型支持示例
     */
    private static void genericExample(DatabaseClient client) {
        log.info("\n=== 泛型支持示例 ===");
        
        // 存储复杂对象
        Map<String, Object> userInfo = new HashMap<>();
        userInfo.put("name", "张三");
        userInfo.put("age", 25);
        userInfo.put("email", "zhangsan@example.com");
        userInfo.put("hobbies", Arrays.asList("读书", "游泳", "编程"));
        
        client.put("complex_user", userInfo);
        log.info("存储了复杂对象");
        
        // 获取复杂对象
        @SuppressWarnings("unchecked")
        Map<String, Object> retrievedUser = client.get("complex_user", Map.class);
        log.info("获取的复杂对象: {}", retrievedUser);
        
        // 存储自定义对象
        KeyValue<String> customKeyValue = new KeyValue<>("custom_key", "custom_value");
        client.put("custom_object", customKeyValue);
        
        KeyValue<String> retrievedCustom = client.get("custom_object", KeyValue.class);
        if (retrievedCustom != null) {
            log.info("获取的自定义对象: key={}, value={}", retrievedCustom.getKey(), retrievedCustom.getValue());
        } else {
            log.info("获取的自定义对象: null");
        }
        
        // 存储数组
        Integer[] numbers = {1, 2, 3, 4, 5};
        client.put("number_array", numbers);
        
        Integer[] retrievedNumbers = client.get("number_array", Integer[].class);
        log.info("获取的数组: {}", Arrays.toString(retrievedNumbers));
    }
    
    /**
     * 性能测试示例
     */
    private static void performanceTest(DatabaseClient client) {
        log.info("\n=== 性能测试示例 ===");
        
        int testCount = 1000;
        
        // 写入性能测试
        long startTime = System.currentTimeMillis();
        for (int i = 0; i < testCount; i++) {
            client.put("perf_key_" + i, "perf_value_" + i);
        }
        long writeTime = System.currentTimeMillis() - startTime;
        log.info("写入{}条数据耗时: {}ms, 平均: {}ms/条", 
                testCount, writeTime, (double) writeTime / testCount);
        
        // 读取性能测试
        startTime = System.currentTimeMillis();
        for (int i = 0; i < testCount; i++) {
            client.get("perf_key_" + i, String.class);
        }
        long readTime = System.currentTimeMillis() - startTime;
        log.info("读取{}条数据耗时: {}ms, 平均: {}ms/条", 
                testCount, readTime, (double) readTime / testCount);
        
        // 批量操作性能测试
        Map<String, Object> batchData = new HashMap<>();
        for (int i = 0; i < 100; i++) {
            batchData.put("batch_perf_key_" + i, "batch_perf_value_" + i);
        }
        
        startTime = System.currentTimeMillis();
        client.batchPut(batchData);
        long batchTime = System.currentTimeMillis() - startTime;
        log.info("批量插入100条数据耗时: {}ms", batchTime);
        
        // 清理测试数据
        for (int i = 0; i < testCount; i++) {
            client.delete("perf_key_" + i);
        }
        for (int i = 0; i < 100; i++) {
            client.delete("batch_perf_key_" + i);
        }
        log.info("清理了测试数据");
    }
    
    /**
     * 显示统计信息
     */
    private static void showStatistics(DatabaseClient client) {
        log.info("\n=== 数据库统计信息 ===");
        
        Map<String, Object> stats = client.getStatistics();
        if (stats != null) {
            log.info("总键数: {}", stats.get("totalKeys"));
            log.info("活跃键数: {}", stats.get("activeKeys"));
            log.info("集合数量: {}", stats.get("collections"));
            log.info("集合名称: {}", stats.get("collectionNames"));
        }
    }
} 